#include "common.h"
#ifdef CAMERA_KERNEL
#include <linux/slab.h>
#define CAMERA_MALLOC(sz) kmalloc(sz,GFP_KERNEL)
#define CAMERA_FREE(ADDR) kfree(ADDR)
#define CAMERA_PRINT printk
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define CAMERA_MALLOC(sz) malloc(sz)
#define CAMERA_FREE(ADDR) free(ADDR)
#define CAMERA_PRINT CAMERA_STDOUT
#endif
#define KUNIT 1024

int test_code = 0;

str_node* remove_node(str_node* node) 
{
	str_node* next = NULL;
	if (!node) return NULL;
	next = node->next;
	CAMERA_FREE(node->str);
	CAMERA_FREE(node);
	return next;
}

str_node* append_node(str_node* node, const char* path)
{
	str_node* newNode = NULL;
	if (!path || !strlen(path)) return NULL;
	newNode = (str_node*)CAMERA_MALLOC(sizeof(str_node));
	newNode->next = NULL;
	newNode->str = (char*)CAMERA_MALLOC(strlen(path) + 1);
	memset(newNode->str, 0, strlen(path) + 1);
	memcpy(newNode->str, path, strlen(path));
	if(node) {
		node->next = newNode;
		newNode->seq = node->seq + 1;
	} else newNode->seq = 0;
	return newNode;
}

void set_save_to(args* ag, const char* path)
{
	if (ag->save_to) CAMERA_FREE(ag->save_to);
	ag->save_to = (char*)CAMERA_MALLOC(strlen(path)+1);
	memset(ag->save_to, 0, strlen(path)+1);
	memcpy(ag->save_to, path, strlen(path));
}

void set_name(args* ag, const char* name)
{
	if (ag->name) CAMERA_FREE(ag->name);
	ag->name = (char*)CAMERA_MALLOC(strlen(name)+1);
	memset(ag->name, 0, strlen(name)+1);
	memcpy(ag->name, name, strlen(name));
}

void set_mount_to(args* ag, const char* path)
{
	if (ag->mount_to) CAMERA_FREE(ag->mount_to);
	ag->mount_to = (char*)CAMERA_MALLOC(strlen(path)+1);
	memset(ag->mount_to, 0, strlen(path)+1);
	memcpy(ag->mount_to, path, strlen(path));
}

void set_log_to(args* ag, const char* path)
{
	if (ag->log_to) CAMERA_FREE(ag->log_to);
	ag->log_to = (char*)CAMERA_MALLOC(strlen(path)+1);
	memset(ag->log_to, 0, strlen(path)+1);
	memcpy(ag->log_to, path, strlen(path));
}

void set_append_space(args* ag, const char* space)
{
	char unit = space[strlen(space)-1];
	char strNum[strlen(space)];
	memset(strNum, 0, strlen(space));
	memcpy(strNum, space, strlen(space)-1);
#ifdef CAMERA_KERNEL
	ag->append_space = simple_strtol(strNum, NULL, 10);
#else
	ag->append_space = atoi(strNum);
#endif
	switch(unit)
	{
	case 'k':
	case 'K':
		break;
	case 'm':
	case 'M':
		ag->append_space *= KUNIT;
	break;
	case 'g':
	case 'G':
		ag->append_space *= KUNIT*KUNIT;
	break;
	default:
		break;
	} 
}

void clean_args(args* ag)
{
	while ((ag->camera_path_head = remove_node(ag->camera_path_head)));
	while ((ag->exclude_path_head = remove_node(ag->exclude_path_head)));
	while ((ag->filter_head = remove_node(ag->filter_head)));
	if (ag->save_to) CAMERA_FREE(ag->save_to);
	if (ag->name) CAMERA_FREE(ag->name);
	if (ag->log_to) CAMERA_FREE(ag->log_to);
	if (ag->mount_to) CAMERA_FREE(ag->mount_to);
	ag->camera_path_head = ag->camera_path_tail = NULL;
	ag->exclude_path_head = ag->exclude_path_tail = NULL;
	ag->filter_head = ag->filter_tail = NULL;
	ag->save_to = ag->name = ag->log_to = ag->mount_to = NULL;
	ag->append_space = 0;
}

void print_args(args* ag)
{
	if (!ag) return;
	if (ag->camera_path_head) {
		CAMERA_PRINT("target path: \n");
		print_str_node(ag->camera_path_head);
	}
	if (ag->exclude_path_head) {
		CAMERA_PRINT("exclude path: \n");
		print_str_node(ag->exclude_path_head);
	}
	if (ag->filter_head) {
		CAMERA_PRINT("filter: \n");
		print_str_node(ag->filter_head);
	}

	if (ag->save_to) CAMERA_PRINT("save_to: \n\t%s\n", ag->save_to);
	if (ag->name)  CAMERA_PRINT("name: \n\t%s\n", ag->name);
	if (ag->log_to) CAMERA_PRINT("log_to: \n\t%s\n", ag->log_to);
	if (ag->mount_to) CAMERA_PRINT("mount_to: \n\t%s\n", ag->mount_to);
	CAMERA_PRINT("append_space: \n\t%dK\n", ag->append_space);
}

void print_str_node(str_node* node)
{
	while (node) {
		CAMERA_PRINT("\t%s\n", node->str);
		node = node->next;
	}
}

